package com.retrofit.starter.config;

import com.retrofit.starter.annotation.RetrofitClient;
import com.retrofit.starter.okhttp.OkHttpClientConfiguration;

import okhttp3.OkHttpClient;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.core.env.Environment;
import retrofit2.Converter;
import retrofit2.Retrofit;


/**
 * @author shanchong
 * @date 2019-06-30
 **/
public class RetrofitFactoryBean implements FactoryBean {

    private Class clazz;
    private Environment environment;
    private BeanFactory beanFactory;

    RetrofitFactoryBean(Class clazz, Environment environment, BeanFactory beanFactory){
        this.clazz = clazz;
        this.environment = environment;
        this.beanFactory = beanFactory;
    }

    @Override
    public Object getObject() throws Exception{
        final RetrofitClient retrofitClient = (RetrofitClient) clazz.getDeclaredAnnotation(RetrofitClient.class);
        final String url = retrofitClient.url();
        final OkHttpClient httpClient = createHttpClient();
        final Retrofit.Builder builder = new Retrofit.Builder()
                .baseUrl(environment.resolvePlaceholders(url));
        if (httpClient!=null){
            builder.client(httpClient);
        }
        final Class<?>[] converterFactoryClasses = retrofitClient.converterFactory();
        for (Class<?> converterFactoryClass : converterFactoryClasses) {
            Converter.Factory converterFactory;
            try {
                converterFactory = (Converter.Factory) converterFactoryClass.getMethod("create").invoke(null);
                builder.addConverterFactory(converterFactory);
            } catch (Exception e) {
                throw new IllegalAccessException(converterFactoryClass+" not find create method ");
            }
        }
        return builder.build().create(clazz);
    }

    private OkHttpClient createHttpClient() {
        final OkHttpClientConfiguration okhttpClientConfiguration = beanFactory.getBean(OkHttpClientConfiguration.class);
        if (okhttpClientConfiguration !=null){
            return okhttpClientConfiguration.getOkHttpClient();
        }
        return null;
    }

    @Override
    public Class<?> getObjectType() {
        return clazz;
    }
}
